<template>
  <div class="app-layout">
    <a-layout class="content-layout">
      <a-layout-sider
          v-if="
          menuType != 2 &&
          !isMobile &&
          !isIframe &&
          currentTopMenu &&
          currentTopMenu.children &&
          currentTopMenu.children.length
        "
          :width="defaultSetting.SECOND_MENU_WIDTH"
      >
        <!-- 二级菜单 -->
        <SubMenus/>
      </a-layout-sider>
      <a-layout-content class="route-content">
        <div
            class="tab-views"
            v-if="menuType == 2 && !isMobile && !isIframe && !showMaxContent"
            :class="isCustomSide ? 'custom-tab-view' : ''"
        >
          <div class="custom-tab-header" v-if="isCustomSide">
            <div class="header-box">
              <a-page-header :title="currentActiveRoute.title" @back="goBack"/>
            </div>
            <RightUserSetting
                @onNoticeClick="onNoticeClick"
                @openInvitation="invitationVisible = true"
                @onPersonalSetting="onPersonalSetting"
                @openCompanyChange="changeCompanyVisible = true"
                @openHelp="helpVisible = true"
                @logout="logout"
            />
          </div>
          <a-tabs
              type="editable-card"
              :activeKey="activeRouteTab"
              @change="onRoutePaneChange"
              @edit="onRoutePaneEdit"
              class="views-tab"
              hideAdd
              :tabBarGutter="0"
          >
            <a-tab-pane
                v-for="(item, index) of routeTabs"
                :key="item.name"
                :closable="item.name != 'home'"
            >
              <template #tab>
                <a-dropdown
                    :trigger="['contextmenu']"
                    overlayClassName="contextmenu-dropdown-layout"
                >
                  <span class="pane-title">
                    {{ $L(item.title) }}
                  </span>
                  <template #overlay>
                    <a-menu
                        @click="
                        ({ key }) => {
                          onTabAction(key, index, item.name, item);
                        }
                      "
                    >
                      <a-menu-item key="reload"> 重新加载</a-menu-item>
                      <a-menu-item
                          key="showMax"
                          :disabled="currentActiveRoute.name !== item.name"
                      >
                        最大化
                      </a-menu-item>
                      <a-menu-divider/>
                      <a-menu-item key="close" :disabled="item.name === 'home'">
                        关闭
                      </a-menu-item>
                      <a-menu-item
                          key="closeOther"
                          :disabled="
                          (routeTabs.length <= 2 && item.name !== 'home') ||
                          routeTabs.length === 1
                        "
                      >
                        关闭其他标签页
                      </a-menu-item>
                      <a-menu-item
                          key="closeRight"
                          :disabled="
                          !(
                            index < routeTabs.length &&
                            routeTabs.length > index + 1
                          )
                        "
                      >
                        关闭右侧标签页
                      </a-menu-item>
                      <a-menu-item
                          key="closeAll"
                          :disabled="routeTabs.length <= 1"
                      >
                        关闭所有标签页
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
                <span
                    class="border-box"
                    v-if="
                    isCustomSide &&
                    index !== 0 &&
                    index !== activeRouteIndex &&
                    index !== activeRouteIndex + 1
                  "
                ></span>
              </template>
            </a-tab-pane>
            <template #rightExtra>
              <RightUserSetting
                  v-if="!isCustomSide"
                  @onNoticeClick="onNoticeClick"
                  @openInvitation="invitationVisible = true"
                  @onPersonalSetting="onPersonalSetting"
                  @openCompanyChange="changeCompanyVisible = true"
                  @openHelp="helpVisible = true"
                  @logout="logout"
              />
              <a-dropdown
                  v-else
                  placement="bottom"
                  :trigger="['click']"
                  overlayClassName="dropdown-type-2-tab-header"
              >
                <template #overlay>
                  <a-menu
                      @click="
                      ({ key }) => {
                        onTabAction(
                          key,
                          activeRouteIndex,
                          currentActiveRoute.name,
                          currentActiveRoute
                        );
                      }
                    "
                  >
                    <a-menu-item key="reload">
                      <SyncOutlined/>
                      刷新
                    </a-menu-item>
                    <a-menu-item key="showMax">
                      <FullscreenOutlined/>
                      最大化
                    </a-menu-item>
                    <a-menu-divider/>
                    <a-menu-item
                        key="close"
                        :disabled="currentActiveRoute.name === 'home'"
                    >
                      <MinusCircleOutlined/>
                      关闭当前
                    </a-menu-item>
                    <a-menu-item
                        key="closeOther"
                        :disabled="
                        (routeTabs.length <= 2 &&
                          currentActiveRoute.name !== 'home') ||
                        routeTabs.length === 1
                      "
                    >
                      <CloseCircleOutlined/>
                      关闭其他
                    </a-menu-item>
                    <a-menu-item key="closeAll">
                      <FolderOutlined/>
                      关闭所有
                    </a-menu-item>
                  </a-menu>
                </template>
                <a-button
                    type="primary"
                    size="small"
                    style="margin-right: 13px"
                >
                  更多
                  <DownOutlined/>
                </a-button>
              </a-dropdown>
            </template>
          </a-tabs>
        </div>
        <div class="route-views">
          <div :style="isAppRoute ? 'height: 100%' : 'height: 0'">
            <app-container></app-container>
          </div>
          <div :style="isAppRoute ? 'height: 0' : 'height: 100%'">
            <router-view
                v-if="isRouteAlive && !$route.meta?.IframePage"
                v-slot="{ Component }"
            >
              <keep-alive :include="keepAliveRoutes">
                <component :is="Component"/>
              </keep-alive>
            </router-view>
            <Iframes
                v-show="$route.name == 'iframes' && currentIframe?.name"
                :currentKey="currentIframe?.query?.key"
                :key="iframeKey"
            />
            <application v-show="$route.name == 'applications'"/>
          </div>
        </div>
      </a-layout-content>
    </a-layout>

    <template v-if="!isMobile">
      <!-- 消息通知弹窗 -->
      <notice-list
          :visible="noticeVisible"
          @cancel="noticeVisible = false"
          @newMessage="noticeVisible = true"
      />
    </template>
    <template v-if="menuType == 2">
      <invitation
          :visible="invitationVisible"
          @close="invitationVisible = false"
      />
      <!-- 帮助与客服 -->
      <help :visible="helpVisible" @close="helpVisible = false"/>
      <!-- 切换公司 -->
      <change-company
          :visible="changeCompanyVisible"
          @close="changeCompanyVisible = false"
      />
    </template>

    <!-- 预览文档 -->
    <ElectronContractModal
        :visible="previewVisible"
        :urlData="previewUrlData"
        :esignDetail="{
        esignCheck: true,
      }"
        title="在线预览"
        @close="previewVisible = false"
    />
  </div>
</template>

<script>
import {reactive, toRefs, computed, watch, nextTick, ref} from "vue";
import SubMenus from "./commonModules/SubMenus.vue";
import utils from "../common/utils/utils";
import routes from "../router/router.config";
import store from "../store";
import {useRoute, useRouter} from "vue-router";
import AppContainer from "./commonModules/AppContainer/index.vue";
import Application from "./commonModules/applications/index.vue";
import defaultSetting from "../common/utils/defaultSetting";
import {
  DownOutlined,
  UsergroupAddOutlined,
  UserOutlined,
  SwapOutlined,
  QuestionCircleOutlined,
  LoginOutlined,
  FullscreenOutlined,
  SyncOutlined,
  MinusCircleOutlined,
  CloseCircleOutlined,
  FolderOutlined,
} from "@ant-design/icons-vue";
import NoticeList from "./commonModules/notice/NoticeList.vue";
import Invitation from "./commonModules/SettingModal/modules/invitation.vue";
import Help from "./commonModules/SettingModal/modules/help.vue";
import ChangeCompany from "./commonModules/SettingModal/modules/ChangeCompany.vue";
import _ from "lodash";
import Iframes from "@/views/iframes/index.vue";
import RightUserSetting from "@/layouts/commonModules/RightUserSetting.vue";
import {message} from "ant-design-vue";
import {mainAppRouter} from "@/router/index";
import ElectronContractModal from "../components/ElectronContractModal/index.vue";

export default {
  name: "AppLayout",
  components: {
    SubMenus,
    AppContainer,
    Application,
    DownOutlined,
    NoticeList,
    Invitation,
    Help,
    ChangeCompany,
    UsergroupAddOutlined,
    UserOutlined,
    SwapOutlined,
    QuestionCircleOutlined,
    LoginOutlined,
    Iframes,
    RightUserSetting,
    FullscreenOutlined,
    SyncOutlined,
    MinusCircleOutlined,
    CloseCircleOutlined,
    FolderOutlined,
    ElectronContractModal,
  },
  setup(props, {emit}) {
    const $route = useRoute();
    const $router = useRouter();
    const isAppRoute = computed(() => $route.path.indexOf("/apps") > -1);
    const currentTopMenu = computed(() => store.getters.currentTopMenu);
    const menuType = computed(() => store.getters.userInfo.pc_menu_type);
    // const menuType = ref(2);
    const appList = computed(() => store.getters.appList);
    const isRouteAlive = ref(true);

    const isMobile = computed(() => store.getters.isMobile);
    const isIframe = computed(() => store.getters.isIframe);

    const isCustomSide = computed(() => !!store.getters.customSideMenu);
    const showMaxContent = computed(() => !!store.getters.showMaxContent);

    const goBack = () => {
      if (window.history.length <= 1) {
        return false;
      } else {
        $router.go(-1);
      }
    };

    const HOME_TAB = {
      name: "home",
      title: "首页",
      query: {},
      path: "/index",
      fullPath: "/index",
    };
    const MAX_COUNT = 10;
    const PERSONNAL_SETTING = {
      id: 1000000000000,
      name: "个人设置",
      parent_id: 0,
      url_type: "path",
      menu_type: 1,
      alias: "personalInfo",
      param: "",
      action: [],
      app: "orgCommon",
      sort: 99998979,
      type: "",
      app_id: 0,
      arrKey: "menu1000000000000",
    };

    const state = reactive({
      keepAliveRoutes: [],
      activeRouteTab: HOME_TAB.name,
      routeTabs: [HOME_TAB],
      noticeVisible: false,
      invitationVisible: false,
      helpVisible: false,
      changeCompanyVisible: false,
      iframeKey: 0,
      previewVisible: false,
      previewUrlData: {
        previewUrl: "",
        url: "",
      },
    });

    window.addEventListener(
        "message",
        (event) => {
          if (!event.data.type && !event.data.status) {
            const message = JSON.parse(event.data);
            if (message?.type != "preview") return;
            state.previewVisible = true;
            state.previewUrlData.previewUrl = message.filePreviewUrl;
            state.previewUrlData.url = message.fileUrl;
          }
        },
        false
    );

    const activeRouteIndex = computed(() =>
        state.routeTabs.findIndex((v) => v.name === state.activeRouteTab)
    );
    const currentActiveRoute = computed(() =>
        state.routeTabs.find((v) => v.name === state.activeRouteTab)
    );

    const iframePages = computed(() =>
        state.routeTabs.filter((v) => v.type === "iframes")
    );
    const currentIframe = computed(() =>
        iframePages.value.find((v) => v.name == state.activeRouteTab)
    );
    const logout = () => {
      utils.modalConfirm({
        content: "确定退出登录吗？",
        centered: true,
        onOk: () => {
          store.dispatch("Logout");
        },
      });
    };

    const reload = (current) => {
      if ($route.name === "iframes") {
        state.iframeKey++;
      } else if (current.type === "app") {
        mainAppRouter.push({
          name: "refresh",
          query: {
            url: encodeURIComponent(`/apps/${current.name}/${current.path}`),
          },
        });
      } else {
        isRouteAlive.value = false;
        nextTick(() => {
          isRouteAlive.value = true;
        });
      }
    };

    const iframeMenus = computed(() => store.getters.iframeMenus);

    const onPersonalSetting = () => {
      $router.push({name: PERSONNAL_SETTING.alias});
    };

    const onNoticeClick = () => {
      state.noticeVisible = true;
    };

    const onRoutePaneEdit = (name, action) => {
      const index = state.routeTabs.findIndex((it) => it.name == name);
      if (state.activeRouteTab == name) {
        onRoutePaneChange(state.routeTabs[index - 1].name);
      }
      state.routeTabs.splice(index, 1);
    };

    const onRoutePaneChange = (name) => {
      if (state.activeRouteTab == name) {
        return;
      }
      const current = state.routeTabs.find((it) => it.name == name);
      if (current.type == "menu") {
        $router.push({name: current.name, query: current.query});
      } else if (current.type == "iframes") {
        $router.push({
          path: `/iframes/${current.query.key}`,
          query: current.query,
        });
      } else {
        $router.push(current.fullPath);
      }
    };

    const onRouteChange = (route) => {
      console.log("route", route);
      if (route.name == "apps") {
        let currentApp = appList.value.find(
            (it) =>
                String(route.fullPath).indexOf(
                    `/apps/${it.app_micro}/${it.app_url}`
                ) !== -1
        );
        let appMicro = "";
        if (currentApp && currentApp.app_micro) {
          appMicro = currentApp.app_micro;
          store.dispatch("SetCurrentApp", currentApp);
          console.log("currentApp2: ", currentApp);
        } else {
          appMicro = route.params.afterApps.split("/")[0];
        }

        const index = state.routeTabs.findIndex((it) => it.name == appMicro);
        console.log("index: ", index);
        if (!currentApp) {
          currentApp = store.getters.currentApp;
        }
        if (index == -1) {
          if (!currentApp) {
            currentApp = store.getters.currentApp;
            console.log("currentApp3: ", currentApp);

            if (menuType == 1) {
              $router.replace(
                  `/apps/${currentApp.app_micro}/${currentApp.app_url}`
              );
              return;
            }
          }
          if (MAX_COUNT == state.routeTabs.length) {
            state.routeTabs.splice(1, 1);
          }
          if (_.isEmpty(currentApp)) {
            appMicro = route.params.afterApps.split("/")[0];
            const index = state.routeTabs.findIndex(
                (it) => it.name == appMicro
            );
            if (index == -1) {
              state.routeTabs.push({
                name: appMicro,
                title: document.title.split(" - ")[0],
                query: {},
                path: route.fullPath,
                fullPath: route.fullPath,
                type: "app",
              });
            } else {
              state.routeTabs[index].name = appMicro;
              state.routeTabs[index].path = route.fullPath;
              state.routeTabs[index].fullPath = route.fullPath;
            }
            state.activeRouteTab = appMicro;
          } else {
            state.routeTabs.push({
              name: currentApp.app_micro,
              title: currentApp.app_name,
              query: {},
              path: currentApp.app_url,
              fullPath: `/apps/${currentApp.app_micro}/${currentApp.app_url}`,
              type: "app",
            });
            state.activeRouteTab = appMicro;
          }
        } else {
          state.routeTabs[index].name = appMicro;
          if (_.isEmpty(currentApp)) {
            state.routeTabs[index].path = route.fullPath;
            state.routeTabs[index].fullPath = route.fullPath;
          } else {
            if (currentApp && currentApp.app_micro) {
              state.routeTabs[index].title = currentApp.app_name;
              state.routeTabs[index].path = currentApp.app_url;
            }
            state.routeTabs[index].fullPath = route.fullPath;
          }
          state.activeRouteTab = appMicro;
        }
      } else if (route.name == "iframes") {
        let current = iframeMenus.value.find(
            (v) => v.arrKey == route.query.key
        );
        const index = state.routeTabs.findIndex(
            (it) => it.name == route.query.key
        );
        if (index == -1) {
          state.routeTabs.push({
            name: route.query.key, // route.query.key
            title: current.name,
            query: {
              ...route.query,
            },
            path: route.fullPath,
            fullPath: route.fullPath,
            type: "iframes",
          });
        } else {
          state.routeTabs[index].name = route.query.key; // route.query.key
          state.routeTabs[index].path = route.fullPath;
          state.routeTabs[index].fullPath = route.fullPath;
        }
        state.activeRouteTab = route.query.key; // route.query.key
      } else {
        const index = state.routeTabs.findIndex((it) => it.name == route.name);

        console.log(
            "not app index: ",
            index,
            route.name,
            route.title,
            route.query
        );
        if (route.name === "refresh" && menuType.value == 2) {
          return;
        }
        if (index == -1) {
          if (MAX_COUNT == state.routeTabs.length) {
            state.routeTabs.splice(1, 1);
          }
          state.routeTabs.push({
            name: route.name,
            title: route.meta.title,
            query: route.query,
            path: route.path,
            fullPath: route.fullPath,
            type: "menu",
          });
        } else {
          state.routeTabs[index].query = route.query;
          state.routeTabs[index].fullPath = route.fullPath;
        }
        state.activeRouteTab = route.name;
      }
    };

    watch($route, onRouteChange);

    const init = () => {
      utils.getKeepAliveRoutes(routes, state.keepAliveRoutes);
      onRouteChange($route);
    };
    init();

    const onRoutePaneDel = (type, index, name) => {
      if (type === "mine") {
        // 关闭自己
        if (state.activeRouteTab == name) {
          onRoutePaneChange(state.routeTabs[index - 1].name);
        }
        state.routeTabs.splice(index, 1);
      } else if (["right", "other"].includes(type)) {
        let _delTabs = [];
        if (type === "right") {
          _delTabs = state.routeTabs.filter((v, i) => i > index);
        } else if (type === "other") {
          _delTabs = state.routeTabs.filter(
              (v, i) => v.name !== "home" && i !== index
          );
        }
        // 当前tab 是否在删除tab 中
        let _currentInDel = _delTabs.filter(
            (v) => v.name === state.activeRouteTab
        );
        // 处理tabs
        if (type === "right") {
          state.routeTabs.splice(index + 1);
        } else if (type === "other") {
          state.routeTabs = state.routeTabs.filter(
              (v, i) => v.name === "home" || i == index
          );
        }
        if (_currentInDel.length) {
          let current = state.routeTabs[state.routeTabs.length - 1];
          if (current.type == "menu") {
            $router.push({name: current.name, query: current.query});
          } else if (current.type == "iframes") {
            $router.push({
              path: `/iframes/${current.query.key}`,
              query: current.query,
            });
          } else {
            $router.push(current.fullPath);
          }
        }
      } else if (type === "all") {
        // 关闭所有
        state.routeTabs.splice(1);
        if (state.activeRouteTab !== "home") {
          $router.push("/index");
        }
      }
    };

    const onTabAction = (key, index, name, current) => {
      switch (key) {
        case "reload":
          if (state.activeRouteTab === name) {
            reload(current);
          } else {
            if (current.type == "menu") {
              $router.push({name: current.name, query: current.query});
            } else if (current.type == "iframes") {
              $router.push({
                path: `/iframes/${current.query.key}`,
                query: current.query,
              });
            } else {
              $router.push(current.fullPath);
            }
            reload(current);
          }
          setTimeout(() => {
            message.success("刷新成功");
          }, 1000);
          break;
        case "close":
          onRoutePaneDel("mine", index, name);
          break;
        case "closeOther":
          onRoutePaneDel("other", index, name);
          break;
        case "closeRight":
          onRoutePaneDel("right", index, name);
          break;
        case "closeAll":
          onRoutePaneDel("all", index, name);
          break;
        case "showMax":
          store.dispatch("setShowMaxContent", true);
          break;
        default:
          break;
      }
    };

    return {
      currentTopMenu,
      isAppRoute,
      defaultSetting,
      menuType,
      isRouteAlive,
      ...toRefs(state),
      onRoutePaneChange,
      onRoutePaneEdit,
      onNoticeClick,
      onPersonalSetting,
      logout,
      onTabAction,
      isMobile,
      isIframe,
      iframePages,
      currentIframe,
      isCustomSide,
      activeRouteIndex,
      currentActiveRoute,
      goBack,
      showMaxContent,
    };
  },
};
</script>

<style scoped lang="less">
.app-layout,
.content-layout,
.route-content {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  // padding-left: 2px;
  .tab-views {
    height: 40px;
    background: #d3e3fd;

    &:deep(.ant-tabs-bar) {
      margin: 0px;
      position: relative;
      width: 100%;
      border-bottom: none;
    }

    :deep(.ant-tabs-tab) {
      background: transparent !important;
      border: none !important;
      border-bottom: 1px solid #e6e7e8;
      position: relative;
      transition: none;

      &:not(:last-child) {
        border-right: 1px solid #f5f6f7 !important;
      }
    }

    :deep(.ant-tabs-tab-active) {
      font-weight: bold;
      background: #f5f6f7 !important;
      border-radius: 4px 4px 0 0 !important;
    }

    .pane-title {
      min-width: 70px;
      display: inline-block;
      text-align: center;
      user-select: none;
    }

    .tab-extra {
      padding-right: 20px;
    }
  }

  .route-views {
    flex: 1;
    overflow: auto;
  }

  .custom-tab-view {
    margin: 10px;
    height: fit-content !important;
    background: transparent !important;

    .views-tab {
      background: #fff;
      height: 40px !important;
      border-bottom-right-radius: 8px;
      border-bottom-left-radius: 8px;

      :deep(.ant-tabs-tab) {
        border: none !important;
      }
    }

    :deep(.ant-tabs-nav-wrap) {
      align-items: flex-end;
    }

    :deep(.ant-tabs-nav-list) {
      height: 34px;
      margin-left: 10px;
    }

    :deep(.ant-tabs-tab) {
      height: 100%;
      position: relative;
      border-radius: 8px 8px 0 0 !important;
      position: relative;
      transition: none;
      color: #000;

      &:hover {
        color: #40a9ff;
      }

      .border-box {
        position: absolute;
        width: 1px;
        height: 16px;
        top: 9px;
        left: 0;
        background-color: #1f2225;
      }
    }

    :deep(.ant-tabs-tab-active) {
      position: relative !important;
      background: #e5e9f7 !important;
      border-left: none !important;
      color: #000 !important;

      &::before {
        position: absolute;
        content: "";
        width: 10px;
        height: 10px;
        background: #e5e9f7;
        left: -10px;
        bottom: 0;
        background: radial-gradient(circle at 0 0,
        transparent 10px,
        #e5e9f7 10px);
      }

      &::after {
        position: absolute;
        content: "";
        width: 10px;
        height: 10px;
        background: #e5e9f7;
        right: -10px;
        bottom: 0;
        background: radial-gradient(circle at 10px 0,
        transparent 10px,
        #e5e9f7 10px);
      }
    }
  }

  :deep(.ant-tabs-card > .ant-tabs-nav .ant-tabs-tab) {
    transition: none;
  }

  .custom-tab-header {
    width: 100%;
    height: 54px;
    background: #fff;
    border-bottom: 1px solid #f1f1f1;
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
    display: flex;
    align-items: center;

    .header-box {
      flex: 1;
      height: 100%;
    }

    :deep(.ant-page-header) {
      height: 100%;
      padding: 0 16px;
      border: none !important;
    }

    :deep(.ant-page-header-heading) {
      height: 100%;
    }
  }
}
</style>

<style lang="less">
.contextmenu-dropdown-layout {
  .ant-dropdown-menu-item {
    font-size: 12px !important;
    padding: 5px 20px;
  }
}

.dropdown-type-2-tab-header {
  .ant-dropdown-menu-item:hover {
    background: #e5eff8 !important;
    color: #005bbc;
  }

  .ant-dropdown-menu-item-disabled:hover {
    background: #fff !important;
    color: rgba(0, 0, 0, 0.25);
  }
}
</style>
